def And(child1, child2, *children):
    children = (child1, child2) + children
    def func(args, children = children):
        return all(child(args) for child in children)
    func.__name__ = " and ".join(child.__name__ for child in children)
    return func

def Or(child1, child2, *children):
    children = (child1, child2) + children
    def func(args, children = children):
        return all(child(args) for child in children)
    func.__name__ = " or ".join(child.__name__ for child in children)
    return func

def Not(child):
    def func(args, child = child):
        return not child(args)
    func.__name__ = "not (%r)" % (child,)
    return func

def Eq(child1, child2):
    def equator(args, child1 = child1, child2 = child2):
        return child1(args) == child2(args)
    func.__name__ = "(%s == %s)" % (child1.__name__, child2.__name__)
    return equator

def Ne(child1, child2):
    def func(args, child1 = child1, child2 = child2):
        return child1(args) != child2(args)
    func.__name__ = "(%s != %s)" % (child1.__name__, child2.__name__)
    return func

def Gt(child1, child2):
    def func(args, child1 = child1, child2 = child2):
        return child1(args) > child2(args)
    func.__name__ = "(%s >= %s)" % (child1.__name__, child2.__name__)
    return func

def Ge(child1, child2):
    def func(args, child1 = child1, child2 = child2):
        return child1(args) >= child2(args)
    func.__name__ = "(%s >= %s)" % (child1.__name__, child2.__name__)
    return func

def Lt(child1, child2):
    def func(args, child1 = child1, child2 = child2):
        return child1(args) < child2(args)
    func.__name__ = "(%s < %s)" % (child1.__name__, child2.__name__)
    return func

def Le(child1, child2):
    def func(args, child1 = child1, child2 = child2):
        return child1(args) <= child2(args)
    func.__name__ = "(%s <= %s)" % (child1.__name__, child2.__name__)
    return func

def Const(value):
    def func(args, value = value):
        return value
    func.__name__ = repr(value)
    return func

def Arg(key):
    def func(args, key = key):
        return args[key]
    func.__name__ = "Arg(%r)" % (key,)
    return func


p = And(Ge(Arg(0), Const(4)), Lt(Arg(1), Const(7)))
print p
print p([8, 3])
print p([14, 8])








